from flask import Flask, request, jsonify
from flask_cors import CORS
from py2neo import Graph, Node, Relationship

# 初始化 Flask 应用
app = Flask(__name__)
# 启用跨域支持
CORS(app)  

# 连接到 Neo4j
graph = Graph("bolt:http://localhost:7474", auth=("neo4j", "714716liu"))

# API: 获取整个知识图谱
@app.route('/get_graph', methods=['GET'])
def get_graph():
    """获取整个知识图谱，包括所有节点和关系"""
    # 查询所有节点
    nodes = []
    for node in graph.nodes.match():
        nodes.append({"id": node["Name"], "label": node["Name"]})

    # 查询所有关系
    relationships = []
    for rel in graph.relationships.match():
        relationships.append({
            "source": rel.start_node["Name"],
            "target": rel.end_node["Name"],
            "label": type(rel).__name__
        })
    
    return jsonify({"nodes": nodes, "relationships": relationships})

# API: 添加节点
@app.route('/add_node', methods=['POST'])
def add_node():
    """添加节点"""
    data = request.json
    node_name = data.get("node_name")
    node_type = data.get("node_type")
    if not node_name:
        return jsonify({"message": "节点名称不能为空！"}), 400

    # 创建节点
    node = Node("Knowledge",category=node_type, Name=node_name,Type="Knowledge")
    
    # 查找匹配的节点
    match_query = "MATCH (n:Knowledge {name: $name}) RETURN n"
    match_result = graph.run(match_query, name=node_name).data()
    
    if match_result:
        # 如果找到匹配的节点，则返回错误信息
        return jsonify({"message": f"节点 {node_name} 已存在！"}), 400
    
    # 如果没有找到匹配的节点，则创建新节点
    graph.create(node)
    
    return jsonify({"message": f"节点 {node_name} 添加成功！"})

#API: 添加关系
@app.route('/add_relationship', methods=['POST'])
def add_relationship():
    """添加关系"""
    data = request.json
    node_name = data.get("node_name")
    node2_name = data.get("node2_name")
    relation_name = data.get("relation_name")

    if not node_name or not node2_name or not relation_name:
        return jsonify({"message": "节点名称和关系名称不能为空！"}), 400

    # 查找节点
    node1 = graph.nodes.match("Knowledge",Name=node_name).first()
    node2 = graph.nodes.match("Knowledge",Name=node2_name).first()
    if not node1 or not node2:
        return jsonify({"message": "节点不存在，无法创建关系！"}), 404

    # 创建关系
    relation = Relationship(node1, relation_name, node2)
    graph.create(relation)
    return jsonify({"message": f"关系 {relation_name} 添加成功！"})

# API: 删除节点
@app.route('/delete_node', methods=['POST'])
def delete_node():
    """删除节点"""
    data = request.json
    node_name = data.get("node_name")
    if not node_name:
        return jsonify({"message": "节点名称不能为空！"}), 400

    # 查找节点
    node = graph.nodes.match("Knowledge",Name=node_name).first()
    if node:
        graph.delete(node)
        return jsonify({"message": f"节点 {node_name} 删除成功！"})
    return jsonify({"message": "节点不存在！"}), 404

# API: 删除关系
@app.route('/delete_relationship', methods=['POST'])
def delete_relationship():
    """删除关系"""
    data = request.json
    node1_name = data.get("node_name")
    node2_name = data.get("node2_name")
    relation_name = data.get("relation_name")

    if not node1_name or not node2_name or not relation_name:
        return jsonify({"message": "节点名称和关系名称不能为空！"}), 400

    # 查找节点
    node1 = graph.nodes.match("Knowledge",Name=node1_name).first()
    node2 = graph.nodes.match("Knowledge",Name=node2_name).first()
    if node1 and node2:
        # 查找关系
        relation = graph.match((node1, node2), r_type=relation_name).first()
        if relation:
            graph.separate(relation)
            return jsonify({"message": f"关系 {relation_name} 删除成功！"})
    return jsonify({"message": "关系不存在！"}), 404

# API: 更新节点属性
@app.route('/update_node', methods=['POST'])
def update_node():
    """更新节点属性"""
    data = request.json
    node_name = data.get("node_name")
    new_properties = data.get("properties", {})

    if not node_name:
        return jsonify({"message": "节点名称不能为空！"}), 400

    # 查找节点
    node = graph.nodes.match(name=node_name).first()
    if node:
        for key, value in new_properties.items():
            node[key] = value
        graph.push(node)
        return jsonify({"message": f"节点 {node_name} 更新成功！"})
    return jsonify({"message": "节点不存在！"}), 404


# API: 获取节点详细信息
@app.route('/get_node_details', methods=['GET'])
def get_node_details():
    """获取节点的详细信息，包括属性和相关关系"""
    node_name = request.args.get("node_name")
    if not node_name:
        return jsonify({"message": "节点名称不能为空！"}), 400

    # 查找节点
    node = graph.nodes.match("Knowledge",Name=node_name).first()
    if not node:
        return jsonify({"message": "节点不存在！"}), 404

    # 获取节点的属性
    node_details = dict(node)

    return jsonify({
        "node": node_details,
    })

if __name__ == '__main__':
    app.run(debug=True)